import { getToken } from '@/utils/auth'
import { Notification } from 'element-ui'
import Vue from 'vue'
import router from '@/router'

// 创建事件总线，用于在不同组件间传递WebSocket消息
export const QcWebSocketBus = new Vue()

class QcWebSocketService {
  constructor() {
    this.ws = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 3000
    this.pingInterval = null
    // 直接连接到后端服务，不通过网关
    this.url = `ws://localhost:9602/websocket/qc?token=${getToken()}`
    // 原配置 - 通过网关连接
    // const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    // const host = window.location.host; // 获取当前主机和端口
    // this.url = `${protocol}//${host}/ldzl-qc/websocket/qc?token=${getToken()}`
    this.connected = false
  }

  // 连接WebSocket
  connect() {
    if (this.ws && this.ws.readyState !== WebSocket.CLOSED) return

    console.log('正在连接质检WebSocket...', this.url)
    try {
      // 捕获WebSocket创建时可能的异常
      try {
        this.ws = new WebSocket(this.url)
      } catch (initError) {
        console.error('创建WebSocket实例失败:', initError)
        this.scheduleReconnect()
        return
      }
      
      this.ws.onopen = this.onOpen.bind(this)
      this.ws.onmessage = this.onMessage.bind(this)
      this.ws.onerror = this.onError.bind(this)
      this.ws.onclose = this.onClose.bind(this)
    } catch (error) {
      console.error('质检WebSocket连接错误:', error)
      this.scheduleReconnect()
    }
  }

  // 连接成功回调
  onOpen() {
    console.log('质检WebSocket连接已建立')
    this.connected = true
    this.reconnectAttempts = 0
    
    // 定期发送心跳包
    this.pingInterval = setInterval(() => {
      this.sendPing()
    }, 30000) // 每30秒发送一次心跳
    
    // 发布连接成功事件
    QcWebSocketBus.$emit('qc-websocket-connected')
  }

  // 接收消息回调
  onMessage(event) {
    try {
      const data = JSON.parse(event.data)
      console.log('收到质检WebSocket消息:', data)
      
      // 根据消息类型处理
      if (data.type === 'quality_check_created') {
        this.handleQualityCheckCreated(data)
      } else if (data.type === 'quality_check_updated') {
        this.handleQualityCheckUpdated(data)
      } else if (data.type === 'work_report_qc_created') {
        this.handleWorkReportQcCreated(data)
      } else if (data.type === 'ping_response') {
        // 心跳响应，不处理
      } else {
        // 其他类型消息，直接发布事件
        QcWebSocketBus.$emit(`qc-${data.type}`, data)
      }
    } catch (error) {
      console.error('解析质检WebSocket消息出错:', error)
    }
  }

  // 处理质检单创建通知
  handleQualityCheckCreated(data) {
    // 显示通知
    this.showNotification({
      title: '新质检单通知',
      message: data.message || '新的质检单已创建，请及时处理',
      type: 'info',
      inspectionType: data.data?.inspectionType
    })
    
    // 发布质检单创建事件
    QcWebSocketBus.$emit('qc-inspection-created', data)
  }

  // 处理质检单更新通知
  handleQualityCheckUpdated(data) {
    // 不显示通知，静默处理
    console.log('收到质检单更新通知，静默处理:', data.message)
    
    // 发布质检单更新事件
    QcWebSocketBus.$emit('qc-inspection-updated', data)
  }

  // 处理报工生成质检单通知
  handleWorkReportQcCreated(data) {
    // 显示通知
    this.showNotification({
      title: '报工生成质检单通知',
      message: data.message || '报工已生成新的质检单，请及时处理',
      type: 'warning',
      inspectionType: data.data?.inspectionType
    })
    
    // 发布报工质检事件
    QcWebSocketBus.$emit('qc-work-report-created', data)
  }

  // 显示系统通知
  showNotification({ title, message, type = 'info', inspectionType }) {
    // 构造通知选项
    let notificationOptions = {
      title,
      message,
      type,
      duration: 0, // 不自动关闭
      position: 'bottom-right',
      onClick: () => {
        // 根据检测单类型跳转到不同页面
        let routePath = ''
        switch (inspectionType) {
          case '1': // 来料检验
            routePath = '/qc/IncomingInspection'
            break
          case '4': // 退料检验
            routePath = '/qc/ReturnInspection'
            break
          case '2': // 默认过程检验
          default:
            routePath = '/qc/ProcesInspection'
        }

        // 关闭通知
        notif.close()
        
        // 跳转到相应页面
        router.push({ path: routePath })
      }
    }
    
    // 显示通知
    const notif = Notification(notificationOptions)
  }

  // 发送心跳包
  sendPing() {
    if (this.connected) {
      this.sendMessage({ type: 'ping' })
    }
  }

  // 发送消息
  sendMessage(message) {
    if (!this.connected) {
      console.warn('质检WebSocket未连接，无法发送消息')
      return false
    }

    try {
      const messageStr = typeof message === 'string' ? message : JSON.stringify(message)
      this.ws.send(messageStr)
      return true
    } catch (error) {
      console.error('发送质检WebSocket消息出错:', error)
      return false
    }
  }

  // 连接错误回调
  onError(event) {
    console.error('质检WebSocket连接错误:', event)
    this.connected = false
    
    // 记录详细错误信息
    console.error('质检WebSocket连接失败。请确保后端服务正常运行在9602端口，并检查WebSocket端点配置。')
    console.error('当前连接URL:', this.url)
    
    // 显示错误通知
    Notification.error({
      title: '质检WebSocket连接错误',
      message: '无法连接到质检WebSocket服务，质检实时通知可能不可用',
      duration: 5000
    })
    
    this.scheduleReconnect()
  }

  // 连接关闭回调
  onClose(event) {
    console.log('质检WebSocket连接已关闭:', event)
    this.connected = false
    
    // 清除心跳定时器
    if (this.pingInterval) {
      clearInterval(this.pingInterval)
      this.pingInterval = null
    }
    
    this.scheduleReconnect()
    
    // 发布连接关闭事件
    QcWebSocketBus.$emit('qc-websocket-disconnected')
  }

  // 安排重连
  scheduleReconnect() {
    // 增加指数退避算法，避免频繁重连
    const backoffTime = Math.min(30000, this.reconnectInterval * Math.pow(1.5, this.reconnectAttempts))
    
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('达到最大重连次数，停止重连')
      
      // 显示通知
      Notification.warning({
        title: '质检WebSocket连接',
        message: '多次尝试连接失败，已停止重连。请刷新页面重试',
        duration: 0
      })
      return
    }

    console.log(`${backoffTime / 1000}秒后尝试重新连接... (尝试 ${this.reconnectAttempts + 1}/${this.maxReconnectAttempts})`)
    
    setTimeout(() => {
      console.log('正在尝试重新连接...')
      this.reconnectAttempts++
      this.connect()
    }, backoffTime)
  }

  // 断开连接
  disconnect() {
    if (!this.ws) return
    
    try {
      this.ws.close()
      this.ws = null
      
      if (this.pingInterval) {
        clearInterval(this.pingInterval)
        this.pingInterval = null
      }
    } catch (error) {
      console.error('关闭质检WebSocket连接时出错:', error)
    }
  }
}

// 导出单例
export default new QcWebSocketService()
